home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 27
/
CU Amiga Magazine's Super CD-ROM 27 (1998)(EMAP Images)(GB)[!][issue 1998-10].iso
/
CUCD
/
Sound
/
SPlayer
/
Socks5
/
src
/
lib
/
addr.c
next >
Wrap
C/C++ Source or Header
|
1998-07-20
|
6KB
|
216 lines
/* Copyright (c) 1995,1996,1997 NEC Corporation. All rights reserved. */
/* */
/* The redistribution, use and modification in source or binary forms of */
/* this software is subject to the conditions set forth in the copyright */
/* document ("Copyright") included with this distribution. */
/*
* $Id: addr.c,v 1.21 1997/06/16 15:29:35 steve Exp $
*/
#include "socks5p.h"
#include "threads.h"
#include "addr.h"
#include "log.h"
IFTHREADED(extern MUTEX_T gh_mutex;)
IFTHREADED(extern MUTEX_T gs_mutex;)
/* Given a name return the network ordered address associated with that */
/* name or INVALIDADDR (-1) on an error. */
int lsName2Addr(const char *name, S5NetAddr *na) {
struct hostent *hp;
if (!name || *name == '\0' || !strcmp(name, "-")) {
return -1;
}
/* XXX needs IPv6 support eventually */
memset(&na->sin, 0, sizeof(ssi));
na->sin.sin_family = AF_INET;
na->sin.sin_addr.s_addr = INVALIDADDR;
if ((na->sin.sin_addr.s_addr = inet_addr((char *)name)) != INVALIDADDR) {
return 0;
}
MUTEX_LOCK(gh_mutex);
if ((hp = REAL(gethostbyname)(name))) memcpy(&na->sin.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length);
MUTEX_UNLOCK(gh_mutex);
return hp?0:-1;
}
/* Given a name return the network ordered port associated with that name, */
/* or INVALIDPORT (-1) on an error. */
int lsName2Port(const char *name, const char *proto, u_short *port) {
struct servent *sp;
if (isdigit(*name)) {
*port = (u_short)atoi(name);
*port = htons(*port);
return 0;
}
MUTEX_LOCK(gs_mutex);
if ((sp = getservbyname((char *)name, proto))) *port = sp->s_port;
MUTEX_UNLOCK(gs_mutex);
if (sp) return 0;
S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Unresolvable service name: %s", name);
*port = INVALIDPORT;
return -1;
}
/* Return 0 if the address is NULL */
int lsAddrIsNull(const S5NetAddr *addr) {
int rval = 0;
switch (addr->sa.sa_family) {
case AF_S5NAME:
if (*addr->sn.sn_name != '\0') rval = -1;
break;
case AF_INET:
if (addr->sin.sin_addr.s_addr != INADDR_ANY && addr->sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) rval = -1;
break;
#ifdef HAVE_NETINET6_IN6_H
case AF_INET6:
if (addr->sin6.sin6_addr != INADDR_ANY && addr->sin6.sin6_addr != htonl(INADDR_LOOPBACK)) rval = -1;
break;
#endif
default:
break;
}
return rval;
}
int lsAddrComp(const S5NetAddr *a1, const S5NetAddr *a2) {
if (a1->sa.sa_family != a2->sa.sa_family) return -1;
switch (a1->sa.sa_family) {
case AF_S5NAME:
if (a1->sn.sn_port != a2->sn.sn_port) return -1;
return strcmp(a1->sn.sn_name, a2->sn.sn_name);
case AF_INET:
if (a1->sin.sin_port != a2->sin.sin_port) return -1;
return memcmp(&a1->sin.sin_addr, &a2->sin.sin_addr, sizeof(struct in_addr));
#ifdef HAVE_NETINET6_IN6_H
case AF_INET6:
if (a1->sin6.sin6_port != a2->sin6.sin6_port) return -1;
return memcmp(&a1->sin6.sin6_addr, &a2->sin6.sin6_addr, sizeof(struct in_addr6));
#endif
default:
return -1;
}
}
int lsAddrAddrComp(const S5NetAddr *a1, const S5NetAddr *a2) {
if (a1->sa.sa_family != a2->sa.sa_family) return -1;
switch (a1->sa.sa_family) {
case AF_S5NAME:
return strcmp(a1->sn.sn_name, a2->sn.sn_name);
case AF_INET:
return memcmp(&a1->sin.sin_addr, &a2->sin.sin_addr, sizeof(struct in_addr));
#ifdef HAVE_NETINET6_IN6_H
case AF_INET6:
return memcmp(&a1->sin6.sin6_addr, &a2->sin6.sin6_addr, sizeof(struct in_addr6));
#endif
default:
return -1;
}
}
void lsAddrCopy(S5NetAddr *dest, const S5NetAddr *src, int len) {
memcpy(dest, src, MIN(len, lsAddrSize(src)));
}
const char *lsAddr2Ascii(const S5NetAddr *na) {
switch (na->sa.sa_family) {
case AF_S5NAME:
return na->sn.sn_name;
case AF_INET:
return inet_ntoa(na->sin.sin_addr);
#ifdef HAVE_NETINET6_IN6_H
case AF_INET6:
return addr2ascii(AF_INET6, (char *)&na->sin6.sin6_addr, sizeof(struct in_addr6), NULL);
#endif
default:
return "";
}
}
u_short lsAddr2Port(const S5NetAddr *na) {
switch (na->sa.sa_family) {
case AF_S5NAME:
return na->sn.sn_port;
case AF_INET:
return na->sin.sin_port;
#ifdef HAVE_NETINET6_IN6_H
case AF_INET6:
return na->sin6.sin6_port;
#endif
default:
return (u_short)0;
}
}
void lsAddrSetPort(S5NetAddr *na, u_short port) {
switch (na->sa.sa_family) {
case AF_S5NAME:
na->sn.sn_port = port;
case AF_INET:
na->sin.sin_port = port;
#ifdef HAVE_NETINET6_IN6_H
case AF_INET6:
na->sin6.sin6_port = port;
#endif
}
}
const char *lsAddr2Ptr(const S5NetAddr *na) {
switch (na->sa.sa_family) {
case AF_S5NAME:
return na->sn.sn_name;
case AF_INET:
return (char *)&na->sin.sin_addr;
#ifdef HAVE_NETINET6_IN6_H
case AF_INET6:
return (char *)&na->sin6.sin6_addr;
#endif
default:
return (char *)&na->sa.sa_data;
}
}
int lsAddrAddrSize(const S5NetAddr *na) {
switch (na->sa.sa_family) {
case AF_S5NAME:
return strlen(na->sn.sn_name);
case AF_INET:
return sizeof(struct in_addr);
#ifdef HAVE_NETINET6_IN6_H
case AF_INET6:
return sizeof(struct in_addr6);
#endif
default:
return 0;
}
}
int lsAddrSize(const S5NetAddr *na) {
switch (na->sa.sa_family) {
case AF_S5NAME:
return sizeof(ssn);
case AF_INET:
return sizeof(ssi);
#ifdef HAVE_NETINET6_IN6_H
case AF_INET6:
return sizeof(ssi6);
#endif
default:
return 0;
}
}